import sys
if '../' not in sys.path:
sys.path.append('../')
from simulab.simulation.core.runner import Runner
from simulab.simulation.core.neighborhood import ExpandedMoore, Moore
from simulab.simulation.core.experiment import ExperimentParametersSet
from simulab.simulation.core.equilibrium_criterion import WithoutCriterion
from src.market import Market
from simulab.simulation.plotters.final_grid import FinalGridSeries
from simulab.simulation.plotters.numerical_series import NumericalSeries
from simulab.simulation.plotters.categorical_animated_lattice import (
CategoricalAnimatedLatticeSeries,
)
from scenarios import monopolios_basic, monopolios_complex
import random, numpy as np
np.random.seed(seed=12345)
random.seed(1234)
Monopolios¶
En esta sección, queremos explorar el efecto que tienen los monopolios sobre el precio de un producto. La idea es observar cómo, en un mercado con poca competencia, los productores son libres de aumentar el precio sin límite (siempre bajo la hipótesis de consumidores con capital ilimitado y demanda constante)
Monopolio absoluto¶
Para empezar, proponemos una configuración básica, en la que cada consumidor tiene un único productor al que le puede comprar. Notar que en este caso, al no haber consumidores compartidos, no hay realmente una señal de precio que compartan los distintos productores. Por lo tanto, no se trata realmente de un sistema complejo, ya que no hay interacciones no lineales entre agentes. Sin embargo, nos pareció un buen punto para comenzar, ya que permite observar comportamientos interesantes que ocurren en el caso límite
experiment_parameters_set = ExperimentParametersSet(
length=[6],
neighborhood=[Moore],
agent_types=[2],
producer_probability=[0.15],
profit_period=[2],
configuration = [monopolios_basic.config],
price_ratio=[(1.2, 5)],
fixed_cost=[(20, 0)],
marginal_cost=[(10, 1)],
quantity_to_buy=[(1,0)],
bankrupt_enabled=[True],
)
criterion = WithoutCriterion()
runner = Runner(Market, experiment_parameters_set, criterion, max_steps=500)
runner.start()
En la siguiente celda, se puede ver la distribución de agentes, donde los amarillos son los productores y los violetas son los consumidores.
En este caso, consideramos un vecindario de Moore tradicional
CategoricalAnimatedLatticeSeries.show_up(
"agent_types_categorized_lattice",
runner=runner,
experiment_id=0,
plot_title="Tipos de agentes de Mercado",
height=400,
)
Al ejecutarlo, podemos ver que rápidamente los productores se dan cuenta de que pueden subir los precios constantemente, aumentando así sus ganancias
CategoricalAnimatedLatticeSeries.show_up(
"price_categorized_lattice",
runner=runner,
experiment_id=0,
plot_title="Evolución del precio en modelo de Mercado",
height=500,
zmin=0,
zmax=300,
)
Se puede ver además que tanto las ganancias de los productores, como los precios de los productos siguen un crecimiento exponencial (con exponente ~0.02, que es el incremento de precio por paso configurado)
productor = (1, 1)
productor_profit_series = [iter[productor[0]][productor[1]] for iter in runner.experiments[0].series['profit_categorized_lattice']]
runner.experiments[0].series['productor_profit_series'] = [profit for profit, agent_type in productor_profit_series]
NumericalSeries.show_up(
"productor_profit_series",
runner=runner,
plot_title="Ganancia de un productor",
yaxis_title="Ganancia",
)
NumericalSeries.show_up(
"average_price",
runner=runner,
plot_title="Precio promedio entre productores y consumidores",
yaxis_title="Precio promedio",
)
Además podemos ver que, luego de un pequeño intervalo en el que prueban hacia donde mover los precios, el incremento porcentual de precios (respecto a t-1) es del 2% (otra vez, indicando que todos los productores están incrementando su precio por el porcentaje definido)
NumericalSeries.show_up(
"average_price_change",
runner=runner,
plot_title="Incremento porcentual de precios (promedio entre productores)",
yaxis_title="Incremento promedio",
)
Además, el incremento porcentual de ganancia también tiende al 2%.
De hecho, es mayor al 2%, porque el costo marginal del producto cada vez se hace más insignificante, a medida que aumenta el precio del mismo
NumericalSeries.show_up(
"average_profit_change",
runner=runner,
plot_title="Incremento porcentual de ganancia (promedio entre productores)",
yaxis_title="Incremento promedio",
)
Aumento en cadena¶
Luego, buscamos otra configuración que presente comportamientos de monopolios (es decir, que haya productores que tienen exclusividad sobre ciertos clientes), pero donde también existan otros consumidores compartidos entre los productores, para permitir la emergencia de comportamientos complejos.
Para eso, generamos una configuración aleatoria, con un 6% de productores, y un 94% de consumidores. Consideramos un vecindario "Expanded Moore (3)"
experiment_parameters_set = ExperimentParametersSet(
length=[20],
neighborhood=[ExpandedMoore(3)],
agent_types=[2],
configuration = [monopolios_complex.config],
producer_probability=[0.06],
profit_period=[2],
# price=[(5,1), (2,1), (10,2), (20,3), (50,5)],
price_ratio=[(1.2, 1.5)],
fixed_cost=[(20, 0)],
marginal_cost=[(10, 1)],
quantity_to_buy=[(1,0)],
bankrupt_enabled=[True],
)
criterion = WithoutCriterion()
runner = Runner(Market, experiment_parameters_set, criterion, max_steps=500)
runner.start()
Como se puede ver, los productores que tienen monopolios sobre ciertas regiones suelen ser los primeros en subir el precio, ya que tienen al menos algunos compradores garantizados.
A su vez, los precios altos permiten que otros productores cercanos eleven sus precios sin perder ventas, por lo que también lo hacen, y esto se propaga hacia el resto de regiones, provocando que finalmente todos los precios se eleven
CategoricalAnimatedLatticeSeries.show_up(
"agent_types_categorized_lattice",
runner=runner,
experiment_id=0,
plot_title="Tipos de agentes de Mercado",
height=400,
)
CategoricalAnimatedLatticeSeries.show_up(
"price_categorized_lattice",
runner=runner,
experiment_id=0,
plot_title="Evolución del precio en modelo de Mercado",
height=500,
zmin=0,
zmax=300,
)